package com.miyu.client1.service.magic.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.miyu.client1.utils.bookUtils.BookCommutils;
import org.apache.commons.lang.StringUtils;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class initDataCommon implements PageProcessor {
    private static String  regex = "\\(([^}]*)\\)";//匹配小括号

    @Override
    public Site getSite() {
        return site;
    }

    //爬虫配置信息设置
    private Site site = new Site()
            .setCharset("utf-8")    //设置编码
            .setSleepTime(2)        //设置抓取间隔
            .setTimeOut(10000)         //设置超时时间
            .setRetrySleepTime(3000)      //设置重试时间
            .setRetryTimes(5);       //设置重试次数


    public static void initData(Request request) {

        Spider.create(new initDataCommon()).addRequest(request)
                .addPipeline(new initSaveData())
                .thread(50)
                .run();
    }

    @Override
    public void process(Page page) {
        Request request = page.getRequest();
        String url=page.getUrl().get();//得到url，起始为http://www.147xs.org/
        //图书规则必带 根据规则解析相关内容
        JSONObject ext  = page.getRequest().getExtra("bookRule");
        //不同的页面
        String type = page.getRequest().getExtra("type");
        if(type.equals("0")){//http://www.147xs.org/book/113568/
            for (int i = 110000; i < 113568; i++) {
                Request reqs = new Request();
                reqs.putExtra("type","1");
                reqs.putExtra("bookRule",ext);
                reqs.setUrl("http://147xs.org/book/"+i);
                page.addTargetRequest(reqs);
                page.setSkip(true);
            }
        }else if(type.equals("1")){
            JSONObject jo = new JSONObject();
            //书籍详情
            //图书ID 使用MD5加密 确定唯一职 后根据此职更新
            String bookId= BookCommutils.MD5(url);
            jo.put("bookId",bookId);
            //作者
            String bookAuthor="//div[@id='maininfo']/div[@id='info']/p[1]/text()tg.lp(：@1)";
            jo.put("bookAuthor",jxRulePage(page, bookAuthor));
            //图片连接
            String bookCover="//div[@id='sidebar']/div[@id='fmimg']/img/@src";
            jo.put("bookCover",jxRulePage(page, bookCover));
            //数据简介
            String bookDuce="//div[@id='maininfo']/div[@id='intro']/text()";
            jo.put("bookDuce",jxRulePage(page, bookDuce));
            //书籍类别
            String bookKind="//div[@class='con_top']/a[2]/text()";
            jo.put("bookKind",jxRulePage(page, bookKind));
            //最后章节名称
            String bookLastChapter="//div[@id='maininfo']/div[@id='info']/p[4]/a/text()";
            jo.put("bookLastChapter",jxRulePage(page, bookLastChapter));
            //最后章节连接页面
            String bookLastChapterUrl="//div[@id='maininfo']/div[@id='info']/p[4]/a/@href";
            jo.put("bookLastChapterUrl",url+jxRulePage(page, bookLastChapterUrl));
            //书名
            String bookName="//div[@id='maininfo']/div[@id='info']/h1/text()";
            jo.put("bookName",jxRulePage(page, bookName));
            //规则来源
            String bookRuleSource;
            jo.put("bookRuleSource","e821e7e079dbe61aaf03ca008b5cetws");
            //来源名称
            String bookSourceName;
            jo.put("bookSourceName","147xs");
            //书籍明细页面
            String bookSource;
            jo.put("bookSource",url);
            //网页主页
            String bookSourceRoot;
            jo.put("bookSourceRoot","http://www.147xs.org/");
            //书籍状态
            String bookState;
            String state = page.getHtml().xpath("//div[@id='sidebar']/div[@id='fmimg']/span/@class").get();
            if(state.equals("a"))
                jo.put("bookState","完结");
            else
                jo.put("bookState","连载");
        List<Selectable> chapter = page.getHtml().xpath("//div[@id='list']/dl/dd").nodes();

            JSONArray chapterList = new JSONArray();
            for (int i=0;i<chapter.size();i++){
                Request req = new Request();
                JSONObject chapterInfo= new JSONObject();
                Selectable selectable = chapter.get(i);
                String chapterName = selectable.xpath("//a/text()").get();
                String chapterUrl = selectable.xpath("//a").links().get();
                chapterInfo.put("bookId",bookId);
                chapterInfo.put("chapterId", BookCommutils.MD5(chapterUrl));
                chapterInfo.put("chapterSource",chapterUrl);
                chapterInfo.put("chapterName",chapterName);
                chapterInfo.put("chapterNum",i);
                chapterInfo.put("chapterContext","");

                req.setUrl(chapterUrl);
                req.putExtra("chapterInfo",chapterInfo);
                req.putExtra("bookInfo",jo);
                req.putExtra("type","2");
                chapterList.add(chapterInfo);
//                page.addTargetRequest(req);
//                page.setSkip(true);
            }
            JSONObject bcInfo  = new JSONObject();
            bcInfo.put("bookInfo",jo);
            bcInfo.put("chapterInfo",chapterList);
            page.putField("bookInfo",bcInfo);

            page.putField("bookId",bookId);
            page.putField("type","1");

        }else if(type.equals("2")){
            //阅读页
           // JSONObject bookInfo = page.getRequest().getExtra("bookInfo");
            JSONObject chapterInfo = page.getRequest().getExtra("chapterInfo");
            String chapterConetxt = page.getHtml().xpath("//div[@id='content']/p").all().toString().replace("\"","").replace(",","");
            chapterInfo.put("chapterContext",StringUtils.strip(chapterConetxt,"[]"));
          //  page.putField("bookInfo",bookInfo);
            page.putField("chapterInfo",chapterInfo);
            page.putField("type","2");
        //    page.putField("bookId",bookInfo.get("bookId"));
        }
    }


    //解析规则 说明
    /**
     * 规则分三段 1 正常取值  2 字符截取   3  字符替换
     * 1.使用 tg. 分割 如果只有正常取值可不加 标志符位
     * 2.字符截取规则 tg.sp(0@2) 字符取substring(0,2)取值, lp(.@1) 指 split(".")分割取 第一个 & 符 合并取值 暂不做复杂处理 tg.sp()&lp() 格式
     * 3.rp 字符替换 tg.rp(我@你) "我"替换 "你",tg.rp(#nbsp@"") 去空格
     * //li[@class='author']/a/text()tg.sp(0@3)&lp(:@1)tg.rp(#nbsp@"")
     *  增加href 取值规则 tg.lk(.@0) 最后取链接 ()取值第几个链接 默认 0 链接默认最后取值 不做分割数据
     */
    private String jxRule(Selectable page , String ruleStr){
        String rs = "";
        if(StringUtils.isNotBlank(ruleStr)){
            String [] tg = ruleStr.split("tg.");
            if(tg.length>0){
                rs =  page.xpath(tg[0]).get();
                for (int i = 1; i < tg.length; i++) {
                    String [] sa = tg[i].split("&");
                    for (String str:sa){
                        if(str.indexOf("lk")>-1){
                            Selectable st = page.xpath(tg[0]);
                            return   rs = regLink(st,page,str);
                        }

                        rs =  reg(rs,str);
                    }
                }
            }else {
                rs =  page.xpath(ruleStr).get();
            }

        }
        return  rs;
    }

    /**
     * 参数page
     * @param page
     * @param ruleStr
     * @return
     */
    private String jxRulePage(Page page ,String ruleStr){
        String rs = "";
        if(StringUtils.isNotBlank(ruleStr)){
            String [] tg = ruleStr.split("tg.");
            if(tg.length>0){
                rs =  page.getHtml().xpath(tg[0]).get();
                for (int i = 1; i < tg.length; i++) {
                    String [] sa = tg[i].split("&");
                    for (String str:sa){
                        if(str.indexOf("lk")>-1){
                            Selectable st = page.getHtml().xpath(tg[0]);
                            return rs = regLinkPage(st,page,str);
                        }

                        rs =  reg(rs,str);
                    }
                }
            }else {
                rs =  page.getHtml().xpath(ruleStr).get();
            }

        }
        return  rs;
    }

    private String regLinkPage(Selectable ob, Page page, String str) {
        String rs = "";
        //取括号内容 之后再分割 取值
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(str);
        String group="";

        while(matcher.find()){
            group = matcher.group(1);
            String [] s = group.split("@");
            if(str.indexOf("lk")>-1){
                if(s.length>1)
                    rs =  ob.xpath("//a").links().get();
                    // rs = ob.replace(s[0],s[1]);
                else
                    rs = ob.toString();
            }
        }
        return  rs;
    }

    private String regLink(Selectable ob, Selectable page, String str) {
        String rs = "";
        //取括号内容 之后再分割 取值
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(str);
        String group="";

        while(matcher.find()){
            group = matcher.group(1);
            String [] s = group.split("@");
            if(str.indexOf("lk")>-1){
                if(s.length>1)
                    rs =  ob.xpath("//a").links().get();
                    // rs = ob.replace(s[0],s[1]);
                else
                    rs = ob.toString();
            }
        }
        return  rs;
    }


    private String reg(String ob ,String str){
        String rs = ob;
        //取括号内容 之后再分割 取值
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(str);
        String group="";

        while(matcher.find()){
            group = matcher.group(1);
        }
        String [] s = group.split("@");
        if(str.indexOf("sp")>-1){
            if(s.length>1)
                rs = ob.substring(Integer.valueOf(s[0]),Integer.valueOf(s[1]));
            else
                rs = ob.substring(Integer.valueOf(s[0]),ob.length());
        }else if(str.indexOf("lp")>-1){
            if(s.length>1)
                if(ob.split(s[0]).length>1)
                    rs = ob.split(s[0])[Integer.valueOf(s[1])];
                else
                    rs = ob;
        }else if(str.indexOf("rp")>-1){
            if(s.length>1)
                rs = ob.replace(s[0],s[1]);
            else
                rs = ob;
        }else if(str.indexOf("lk")>-1){
            if(s.length>1)
                rs = ob.replace(s[0],s[1]);
            else
                rs = ob;
        }
        return  rs;
    }
}
